package com.chinacoal.hr.levelimpl.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chinacoal.hr.levelapi.entity.BizTravel;
import com.chinacoal.hr.levelapi.entity.BizTravelEmp;
import com.chinacoal.hr.levelapi.entity.TransPaperDetailList;
import com.chinacoal.hr.levelimpl.dao.BizTravelDao;
import com.chinacoal.hr.levelimpl.service.*;
import com.chinacoal.hr.levelimpl.utils.StaticDicts;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author: YunTao.Li
 * @create: 2019-11-19 16:22
 * @description: 出差申请单service实现类
 **/
@Service
public class BizTravelServiceImpl implements BizTravelService {

    @Autowired
    private BizTravelDao bizTravelDao;

    @Autowired
    private TransPaperDetailListService transPaperDetailListService;

    @Autowired
    private BizTravelEmpService bizTravelEmpService;

    @Autowired
    private FileInfoService fileInfoService;

    @Autowired
    private WorkflowService workflowService;

    /**
     * service实现：查询出差申请单列表
     *
     * @param condition :
     * @return : com.baomidou.mybatisplus.core.metadata.IPage<com.chinacoal.hr.levelimpl.entity.BizTravel>
     * @author : YunTao.Li
     * @date : 2019/11/19 2019/11/19
     */
    public IPage<BizTravel> getBizTravelList(Map<String, Object> condition) throws Throwable {
        IPage<BizTravel> BizTravelList = bizTravelDao.getBizTravelList(condition);
        return BizTravelList;
    }

    /**
     * 根据查询条件获得出差单信息
     *
     * @param condition :
     * @return : com.chinacoal.hr.levelimpl.entity.BizTravel
     * @author : YunTao.Li
     * @date : 2019/11/27 2019/11/27
     */
    @Override
    public BizTravel getBizTravelByCondition(Map<String, Object> condition) throws Throwable {
        // step1 : 根据查询条件获得出差单信息
        BizTravel travelInfo = this.bizTravelDao.getBizTravelInfo(condition);
        String travelId = travelInfo.getBizTravelId();

        // step2 : 获得随同人员信息
        Map empCondition = new HashMap();
        empCondition.put("travelId", travelId);
        List<BizTravelEmp> bizTravelEmps = this.bizTravelEmpService.getBizTravelEmpsWithOutPage(empCondition);

        // 将列表加入travel实体
        travelInfo.setBizTravelEmpList(bizTravelEmps);

        return travelInfo;
    }


    /**
     * service实现：新增出差申请单列表
     *
     * @param record :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/11/19 2019/11/19
     */
    @Transactional
    public Map<String, String> insertBizTravel(BizTravel record) {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            // step1 : 新增出差申请单
            bizTravelDao.insertBizTravel(record);

            String travelId = record.getBizTravelId();

            // step2 : 如果有随同人员，要增加随同人员信息
            List<BizTravelEmp> travelEmpList = record.getBizTravelEmpList();
            if (travelEmpList != null && travelEmpList.size() > 0) {
                for (BizTravelEmp travelEmp : travelEmpList) {
                    travelEmp.setBizTravelId(travelId);
                    bizTravelEmpService.insertBizTravelEmp(travelEmp);
                }
            }

            // step3 : 修改相关文件的临时paDocId为正式paDocId
            String realPaDocId = travelId;
            String tempPaDocId = record.getFileParamPaDocId();

            fileInfoService.updatePaDocId(tempPaDocId, realPaDocId);
        } catch (Throwable e) {
            e.printStackTrace();
        }

        result.put("code", "1");
        return result;
    }

    /**
     * service实现：更新出差申请单列表
     *
     * @param record :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/11/19 2019/11/19
     */
    @Transactional
    public Map<String, String> updateBizTravel(BizTravel record) throws Throwable {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            // step1 : 更新出差单信息
            String bizTravelId = record.getBizTravelId();
            bizTravelDao.updateBizTravel(record);

            // step2 : 先删除随同人员信息，再插入随同人员信息
            bizTravelEmpService.deleteBizTravelEmpByTravelId(bizTravelId);

            // step3 : 插入新的随同人员信息
            List<BizTravelEmp> travelEmpList = record.getBizTravelEmpList();
            if (travelEmpList != null && travelEmpList.size() > 0) {
                for (BizTravelEmp travelEmp : travelEmpList) {
                    travelEmp.setBizTravelId(bizTravelId);
                    bizTravelEmpService.insertBizTravelEmp(travelEmp);
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        }

        result.put("code", "1");
        return result;
    }

    /**
     * service实现：删除出差申请单列表
     *
     * @param bizTravelId :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/11/19 2019/11/19
     */
    @Transactional
    public Map<String, String> deleteBizTravel(String bizTravelId) {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            //step1 : 删除出差申请单
            bizTravelDao.deleteBizTravelById(bizTravelId);

            //step2 : 删除随同人员
            bizTravelEmpService.deleteBizTravelEmpByTravelId(bizTravelId);

        } catch (Throwable e) {
            e.printStackTrace();
        }

        result.put("code", "1");
        return result;
    }

    /**
     * 提交出差申请单
     *
     * @param record :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/11/27 2019/11/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, String> submitBizTravel(BizTravel record) throws Throwable {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            String bizTravelId = record.getBizTravelId();
            Date startDate = record.getStartDate();
            String startTimeType = record.getStartTimeType();
            Date endDate = record.getEndDate();
            String endTimeType = record.getEndTimeType();
            String paType = StaticDicts.HR_PA_TYPE_TRAVEL;
            String docTypeId = "e1c4b2f3-87e5-11e7-b512-7a07f6fc3890";
            String empCode = record.getEmpCode();
            String insCode = record.getInsCode();

            // 判断之前有没有创建过流程，还是撤回后再二次提交
            if (StringUtils.isBlank(insCode)) {
                String empName = record.getEmpName();
                String code = record.getBizTravelCode();
                String processInstTitle = "请审批 " + empName + " 提交的编码为:" + code + "的因事外出申请单";

                // step1 : 创建并启动流程，获得processInstID
                String processInstID = workflowService.createAndStartAndFinishFirstWorkitem(WorkflowServiceImpl.PROCESSDEFNAME_TRAVEL, processInstTitle, null, bizTravelId, record);
                record.setInsCode(processInstID); //出差申请表，记录流程实例编码
            } else {

                // step1 : 二次提交，直接完成工作项
                workflowService.createAndStartAndFinishFirstWorkitem(WorkflowServiceImpl.PROCESSDEFNAME_TRAVEL, null, insCode, bizTravelId, record);
            }

            // step1 : 首先，将出差单的状态改为C，已提交
            record.setBusinessStatus(StaticDicts.BUSINESS_STATUS_SUBMITTED);

            // step2 : 更新出差申请表,
            bizTravelDao.updateBizTravel(record);

            // step3 : 创建员工事务天数统计明细表(出差不记这个表)
//        this.transPaperDetailService.submitTransPaperDetail(bizTravelId, createDate, holidayType, String.valueOf(days));

            //step4 : 员工事务单汇总表,按天数循环，每天一条记录
            this.transPaperDetailListService.submitTransPaperDetailList(bizTravelId, docTypeId, paType, empCode, startDate, startTimeType, endDate, endTimeType, paType);

        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        }
        result.put("code", "1");
        return result;
    }

    /**
     * 撤回出差申请单
     *
     * @param travel :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/12/12 2019/12/12
     */
    @Override
    @Transactional
    public Map<String, String> drawbackBizTravel(BizTravel travel) throws Throwable {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");

        try {
            // step1 : 完成工作项,撤回
            String processInstID = travel.getInsCode();
            String travelId = travel.getBizTravelId();
            String approvalContext = "测试出差审批意见：撤回";
            workflowService.finishWorkitem(Long.parseLong(processInstID), 0, approvalContext, WorkflowServiceImpl.WORKITEM_OPCODE_DRAWBACK);

            //step3 : 修改出差申请单xip_hr_biz_travel的审批状态BUSINESS_STATUS为A草稿
            travel.setBusinessStatus(StaticDicts.BUSINESS_STATUS_DRAWBACK);
            this.bizTravelDao.updateBizTravel(travel);

            //step4 : 删除xip_hr_pa_list员工事务单汇总表的数据
            transPaperDetailListService.deleteTransPaperDetailListByDocId(travelId);
        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        }

        result.put("code", "1");
        return result;
    }

    /**
     * 变更出差申请单
     *
     * @param record :
     * @return : java.util.Map<java.lang.String,java.lang.String>
     * @author : YunTao.Li
     * @date : 2019/12/4 2019/12/4
     */
    @Override
    @Transactional
    public Map<String, String> changeBizTravel(BizTravel record) throws Throwable {
        Map<String, String> result = new HashMap<String, String>();
        result.put("code", "-1");
        try {
            // step1 : 更新出差单信息
            String bizTravelId = record.getBizTravelId();
            bizTravelDao.updateBizTravel(record);

            // step2 : 先删除随同人员信息，再插入随同人员信息
            bizTravelEmpService.deleteBizTravelEmpByTravelId(bizTravelId);

            // step3 : 插入新的随同人员信息
            List<BizTravelEmp> travelEmpList = record.getBizTravelEmpList();
            if (travelEmpList != null && travelEmpList.size() > 0) {
                for (BizTravelEmp travelEmp : travelEmpList) {
                    travelEmp.setBizTravelId(bizTravelId);
                    bizTravelEmpService.insertBizTravelEmp(travelEmp);
                }
            }

            // step4 : 删除员工事务单汇总表
            this.transPaperDetailListService.deleteTransPaperDetailListByDocId(bizTravelId);

            // step5 : 插入新的员工事务单汇总表
            Date startDate = record.getStartDate();
            String startTimeType = record.getStartTimeType();
            Date endDate = record.getEndDate();
            String endTimeType = record.getEndTimeType();
            String paType = StaticDicts.HR_PA_TYPE_TRAVEL;
            String docTypeId = StaticDicts.DOC_TYPE_ID_TRAVE_CHANGE;
            String empCode = record.getEmpCode();
            this.transPaperDetailListService.submitTransPaperDetailList(bizTravelId, docTypeId, paType, empCode, startDate, startTimeType, endDate, endTimeType, paType);

            // step6 : 修改事务单的状态为已审批
            TransPaperDetailList template = new TransPaperDetailList();
            template.setPaDocId(bizTravelId);
            TransPaperDetailList value = new TransPaperDetailList();
            value.setBusinessStatus(StaticDicts.BUSINESS_STATUS_APPROVALED);
            this.transPaperDetailListService.updateTransPaperDetailListByTemplate(template, value);
        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        }
        result.put("code", "1");
        return result;
    }
}
